<?php
namespace App\Exceptions;

use App\Api\Exceptions\ApiCommonException;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\Response;
use App\Api\Helpers\ApiResponse;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Database\QueryException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Illuminate\Database\Eloquent\ModelNotFoundException;

/**
 * api异常处理类
 *
 * 处理异常
 *
 * 2018年4月23日 下午3:01:29
 *
 * @category PHP
 * @package B2C
 * @author lijian <lij25@mingyuanyun.com>
 * @copyright 2018 Mingyuanyun
 * @version 1.0.0
 */
class ApiHandler extends ExceptionHandler
{
    use ApiResponse;

    protected $dontReport = [
        ApiCommonException::class,
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        if (app()->environment('production') && $this->shouldReport($exception)) {
            app('sentry')->captureException($exception);
        }
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        $trace = $exception->getTrace();
        $code = $exception->getCode();
        $message = $exception->getMessage();
        $exceptionClassName = get_class($exception);
        $httpCode = Response::HTTP_OK;
        switch ($exceptionClassName){
            case NotFoundHttpException::class:
                $code = $httpCode = Response::HTTP_NOT_FOUND;
                $message = '无效的接口';
                break;
            case ModelNotFoundException::class:
                $code = $httpCode = Response::HTTP_NOT_FOUND;
                $message = '数据不存在';
                break;
            case MethodNotAllowedHttpException::class:
                $code = $httpCode = $exception->getStatusCode();
                $message = '不支持的请求方式';
                break;
            case AuthenticationException::class:
                $code = $httpCode = Response::HTTP_UNAUTHORIZED;
                $message = '无效的认证token';
                break;
            case QueryException::class:
                $code = $exception->getCode();
                $message = '数据库异常';
                break;
            case ApiCommonException::class:
                break;
            default:
                if ($exception instanceof HttpException) {
                    $code = $exception->getStatusCode();
                    $message = isset(Response::$statusTexts[$code]) ? Response::$statusTexts[$code] : '请求异常';
                } else {
                    $code = Response::HTTP_INTERNAL_SERVER_ERROR;
                    $message = '系统发生异常，请稍后重试';
                }
        }

        $return = $this->getResponseFail($code ,$message ,null ,$trace);
        return response($return ,$httpCode);
    }
}